//
//  CpuUsageMonitor.swift
//  AICleaner
//
//  Created by firefly on 2025/1/26.
//

import Foundation
import Combine

class DeviceMonitor {
    private var timer: DispatchSourceTimer?
    private var cancellables = Set<AnyCancellable>()
    private var previousCpuTicks = host_cpu_load_info().cpu_ticks

    func startMonitoring(interval: TimeInterval = 1.0, onUpdate: @escaping (_ cpuUsage: Double, _ memoryUsed: Double) -> Void) {
        let queue = DispatchQueue(label: "com.example.cpuMonitor", qos: .userInteractive)
        timer = DispatchSource.makeTimerSource(queue: queue)
        timer?.schedule(deadline: .now(), repeating: interval)
        timer?.setEventHandler { [weak self] in
            guard let self = self else { return }
            let cpuUsage = self.getCPUUsage()
            let (memoryUsed, total) = self.getMemoryUsage()
            DispatchQueue.main.async {
                onUpdate(cpuUsage,memoryUsed)
            }
        }
        timer?.resume()
    }
    
    func stopMonitoring() {
        timer?.cancel()
        timer = nil
    }
    
    /// 内存使用监控
    private func getMemoryUsage() -> (used: Double, total: Double) {
        var taskInfo = mach_task_basic_info()
        var count = mach_msg_type_number_t(MemoryLayout<mach_task_basic_info>.size) / 4

        let result = withUnsafeMutablePointer(to: &taskInfo) {
            $0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) {
                task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count)
            }
        }

        if result == KERN_SUCCESS {
            let used = Double(taskInfo.resident_size) / 1024 / 1024 // MB
            let total = Double(ProcessInfo.processInfo.physicalMemory) / 1024 / 1024 // MB
            return (used, total)
        }

        return (0, 0)
    }
    
    /// cpu使用率监控
    private func getCPUUsage() -> Double {
       var cpuInfo = host_cpu_load_info()
       var count = mach_msg_type_number_t(MemoryLayout<host_cpu_load_info>.size / MemoryLayout<integer_t>.size)

       let result = withUnsafeMutablePointer(to: &cpuInfo) {
           $0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) {
               host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, $0, &count)
           }
       }

       if result == KERN_SUCCESS {
           let userDiff = Double(cpuInfo.cpu_ticks.0 - previousCpuTicks.0)
           let systemDiff = Double(cpuInfo.cpu_ticks.1 - previousCpuTicks.1)
           let idleDiff = Double(cpuInfo.cpu_ticks.2 - previousCpuTicks.2)
           let niceDiff = Double(cpuInfo.cpu_ticks.3 - previousCpuTicks.3)

           let totalTicks = userDiff + systemDiff + idleDiff + niceDiff
           let usedTicks = userDiff + systemDiff + niceDiff

           previousCpuTicks = cpuInfo.cpu_ticks

           if totalTicks > 0 {
               return (usedTicks / totalTicks) * 100.0
           }
       }

       return 0.0
   }
}
